#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int arr[maxn];
vector<int> ma;
int root[maxn], tot;
inline void init() {
  memset(root, 0, sizeof(root));
  tot = 0;
  ma.clear();
}
int getid(int x) {
  return lower_bound(ma.begin(), ma.end(), x) - ma.begin() + 1;
}
struct SegTree {
  using arr = int[maxn << 5];
  arr lson, rson, sum;
  void pushup(int rt) { sum[rt] = sum[lson[rt]] + sum[rson[rt]]; }
  void build(int l, int r, int &rt) {
    rt = ++tot;
    if (l == r) {
      sum[rt] = 0;
      return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, lson[rt]);
    build(mid + 1, r, rson[rt]);
    pushup(rt);
  }
  void update(int pos, int val, int l, int r, int ord, int &rt) {
    rt = ++tot;
    lson[rt] = lson[ord];
    rson[rt] = rson[ord];
    if (l == r) {
      sum[rt] = sum[ord] + val;
      return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid)
      update(pos, val, l, mid, lson[ord], lson[rt]);
    else
      update(pos, val, mid + 1, r, rson[ord], rson[rt]);
    pushup(rt);
  }
  int query(int k, int l, int r, int lrt, int rrt) {
    if (l == r) return l;
    int mid = (l + r) >> 1;
    int cnt = sum[lson[rrt]] - sum[lson[lrt]];
    if (k <= cnt)
      return query(k, l, mid, lson[lrt], lson[rrt]);
    else
      return query(k - cnt, mid + 1, r, rson[lrt], rson[rrt]);
  }
} seg;
int main() {
  int n, q;
  while (scanf("%d%d", &n, &q) == 2) {
    init();
    seg.build(1, n, root[0]);
    for (int i = 1; i <= n; ++i) scanf("%d", &arr[i]), ma.push_back(arr[i]);
    sort(ma.begin(), ma.end());
    ma.erase(unique(ma.begin(), ma.end()), ma.end());
    for (int i = 1; i <= n; ++i) {
      seg.update(getid(arr[i]), 1, 1, n, root[i - 1], root[i]);
    }
    while (q--) {
      int l, r, k;
      scanf("%d%d%d", &l, &r, &k);
      int ans = seg.query(k, 1, n, root[l - 1], root[r]);
      printf("%d\n", ma[ans - 1]);
    }
  }
}
